home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /* */
- /* atoi_ex, atou_ex, atol_ex, atoul_ex */
- /* Convert a string to an integer extended */
- /* */
- /* NAME */
- /* atoi_ex...................Convert a string to an integer */
- /* atou_ex...................Convert a string to an unsigined */
- /* atol_ex...................Convert a string to a long */
- /* atoul_ex..................Convert a string to an unsigned long */
- /* */
- /* SYNOPSIS */
- /* result = atoi_ex(p, i); */
- /* result = atou_ex(p, u); */
- /* result = atol_ex(p, l); */
- /* result = atoul_ex(p, ul) */
- /* */
- /* int result Result of conversion */
- /* 0 for end of non-empty input string */
- /* 1 for non-numeric character after non-empty */
- /* input string */
- /* 2 for empty input string */
- /* 3 for non_numeric character after empty input */
- /* string */
- /* 4 for overflow */
- /* char **p At start, *p points to the string to be converted */
- /* At end, *p points to the terminating character. */
- /* In the case of overflow, *p points at the */
- /* character which caused it. */
- /* int *i Pointer to converted integer */
- /* unsigned *u Pointer to converted unsigned */
- /* long *l Pointer to converted long */
- /* unsigned long *ul Pointer to converted unsigned long */
- /* */
- /* DESCRIPTION */
- /* The atov_ex functions are extensions of ANSI functions atov. They */
- /* each convert the string *p to the proper form of integer. They */
- /* extend the standard ANSI functions in three ways: */
- /* 1. They skip leading white space. */
- /* 2. They return a pointer to the character of the string after the */
- /* integer. */
- /* 3. They return a result code for the terminating condition. In */
- /* particular, they all check for overflow. */
- /* If the input string is empty or has no digits, they all leave the */
- /* value of their integer unchanged. This feature allows for default */
- /* values. */
- /* */
- /* CAUTIONS */
- /* Since the ANSI functions return the calculated integer, these */
- /* functions have a fundamentally different syntax. They all require */
- /* an integer value to store this result in. */
- /* These functions are specific to the 8088 and its family. In */
- /* addition, _natoil.asm, which actually does most of the work for */
- /* them, uses Lattice C, Version 3.10 conventions and DOS.MAC, the */
- /* Lattice INCLUDE file which implements them. They should be */
- /* compatible with Version 3.00 as well. I am not sure about */
- /* Version 2 or other brands of C */
- /* */
- /* RETURNS */
- /* All functions return an integer result code. */
- /* */
- /* EXAMPLES */
- /* */
- /* Assume that s contains " -1000000, 50000". */
- /* */
- /* char **p; */
- /* long l1, l2; */
- /* */
- /* p = &s; */
- /* if (atol_ex(p, &l1) == 4) */
- /* { */
- /* fputs("Overflow", stderr); */
- /* break; */
- /* } */
- /* */
- /* *p points to the comma, and *l2 contains -1000000. The function */
- /* actually returned 1. */
- /* */
- /* if (atol_ex(p, &l2) == 4) */
- /* { */
- /* fputs("Overflow", stderr); */
- /* break; */
- /* } */
- /* */
- /* *p points to the NULL at the end of s, and *l2 contains 50000. */
- /* The function actually returned 0. */
- /* */
- /***************************************************************************/
- /* */
- /* COMPILATION */
- /* Compile the four functions for the small model with Lattice C as: */
- /* "lcs -oatoi_ex atov_ex" for atoi_ex.obj */
- /* "lcs -oatol_ex -dL_EX atov_ex" for atol_ex.obj */
- /* "lcs -oatou_ex -dU_EX atov_ex" for atou_ex.obj */
- /* "lcs -oatoul_ex -dL_EX -dU_EX atov_ex" for atoul.obj */
- /* For other memory models, change "lcs" to the proper compiler call */
- /* */
- /* Written by: Lew Paper */
- /* Date written: 8/28/86 */
- /* */
- /***************************************************************************
- */
-
- #include <limits.h>
-
- #ifdef L_EX /* Long */
- #define _NATOV _natol /* Inner conversion function */
- #define NINT_TYPE unsigned long /* Type of value from _NATOV */
- #ifdef U_EX /* Unsigned long */
- #define ATOV_EX atoul_ex /* Function name */
- #define INTEGER ul /* Converted value */
- #define INT_TYPE unsigned long /* Type of INTEGER */
- #define MAX_VALUE ULONG_MAX /* Maximum value for type */
- #else /* Signed long */
- #define ATOV_EX atol_ex /* Function name */
- #define INTEGER l /* Converted value */
- #define INT_TYPE long /* Type of INTEGER */
- #define MAX_VALUE LONG_MAX /* Maximum value for type */
- #define MIN_VALUE LONG_MIN /* Minimum value for type */
- #endif /* #ifdef U_EX */
- #else /* Standard length */
- #define _NATOV _natoi /* Inner conversion function */
- #define NINT_TYPE unsigned /* Type of value from _NATOV */
- #ifdef U_EX /* Unsigned int */
- #define ATOV_EX atou_ex /* Function name */
- #define INTEGER u /* Converted value */
- #define INT_TYPE unsigned /* Type of converted value */
- #define MAX_VALUE UINT_MAX /* Maximum value for type */
- #else /* Signed int */
- #define ATOV_EX atoi_ex /* Function name */
- #define INTEGER i /* Converted value */
- #define INT_TYPE int /* Type of converted value */
- #define MAX_VALUE INT_MAX /* Maximum value for type */
- #define MIN_VALUE INT_MIN /* Minimum value for type */
- #endif /* #ifdef U_EX */
- #endif /* #ifdef L_EX */
-
- int ATOV_EX(p, INTEGER)
- char **p;
- INT_TYPE *INTEGER;
-
- {
- #ifndef U_EX /* Unsigned */
- int sign; /* -1 if negative */
- #endif /* #ifndef U_EX */
- int result;
- union
- {
- NINT_TYPE ninteger; /* Value from _NATOV - the */
- /* inner conversion */
- INT_TYPE cinteger; /* Value for outer */
- /* conversion */
- } number;
-
- while (isspace(**p)) /* Skip white space */
- (*p)++;
-
- #ifndef U_EX /* Check for sign */
- sign = 1; /* Assume positive */
- switch (**p)
- {
- case '-':
- sign = -1; /* Negative */
- (*p)++; /* Next character */
- break;
- case '+':
- (*p)++; /* Next character */
- break;
- }
- #endif /* #ifndef U_EX */
-
- result = _NATOV(p, &number.ninteger);
- switch (result)
- {
- #ifdef U_EX /* Unsigned */
- case 0: /* Number at end of string */
- case 1: /* Number inside string */
- *INTEGER = number.cinteger;
- break;
-
- case 4: /* Overflow */
- *INTEGER = MAX_VALUE; /* Maximum possible value */
- break;
- #else /* Signed */
- case 0: /* Number at end of string */
- case 1: /* Number inside string */
- if (number.cinteger >= 0) /* No overflow? */
- { /* Yes */
- if (sign < 0)
- *INTEGER = -number.cinteger;
- else
- *INTEGER = number.cinteger;
- }
- else
- {
- if (sign < 0)
- {
- if (number.cinteger > MIN_VALUE) /* Is it overflow? */
- result = 4; /* Yes */
- *INTEGER = MIN_VALUE; /* Minium possible value */
- }
- else /* Positive value must be */
- /* overflow */
- {
- *INTEGER = MAX_VALUE; /* Maximum possible value */
- result = 4;
- }
- }
- break;
-
- case 4: /* Overflow */
- if (sign < 0)
- *INTEGER = MIN_VALUE; /* Minimum possible value */
- else
- *INTEGER = MAX_VALUE; /* Maximum possible value */
- break;
- #endif /* #ifdef U_EX */
- }
-
- return(result);
- }